package com.automotive.can1939.ui;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.automotive.can1939.R;
import com.automotive.can1939.can.CanDataParser;
import com.automotive.can1939.can.CanManager;
import com.automotive.can1939.can.CanTestDataGenerator;
import com.automotive.can1939.can.J1939Constants;
import com.automotive.can1939.can.J1939DataParser;
import com.automotive.can1939.model.CanFrame;
import com.automotive.can1939.model.J1939Frame;
import com.automotive.can1939.service.CanCommunicationService;
import com.automotive.can1939.ui.adapter.CanFrameAdapter;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import timber.log.Timber;

/**
 * 主活动 - CAN通信大屏界面
 */
public class MainActivity extends AppCompatActivity implements
        CanManager.CanDataListener, CanManager.CanStatusListener,
        CanCommunicationService.ServiceListener {

    private static final String TAG = "MainActivity";

    // UI组件
    private TextView tvConnectionStatus;
    private Button btnConnect, btnDisconnect;
    private Button btnSendTestData, btnClearData;
    private EditText etCanId, etCanData;
    private Button btnSendCustom, btnSendJ1939Test;
    private RecyclerView rvCanFrames;
    private TextView tvFrameCount, tvProtocolStatus;

    // 数据和适配器
    private CanManager canManager;
    private CanFrameAdapter frameAdapter;
    private List<CanFrame> frameList;

    // 记录自己发送的帧（用于区分自发和他发）
    private Set<String> sentFrameIds = new HashSet<>();

    // 服务相关
    private CanCommunicationService canService;
    private boolean isServiceBound = false;
    private Intent serviceIntent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initViews();
        initData();
        setupListeners();
        startAndBindService();

        Timber.d("MainActivity创建完成");
    }

    /**
     * 初始化视图
     */
    private void initViews() {
        tvConnectionStatus = findViewById(R.id.tv_connection_status);
        btnConnect = findViewById(R.id.btn_connect);
        btnDisconnect = findViewById(R.id.btn_disconnect);
        btnSendTestData = findViewById(R.id.btn_send_test_data);
        btnClearData = findViewById(R.id.btn_clear_data);
        etCanId = findViewById(R.id.et_can_id);
        etCanData = findViewById(R.id.et_can_data);
        btnSendCustom = findViewById(R.id.btn_send_custom);
        btnSendJ1939Test = findViewById(R.id.btn_send_j1939_test);
        rvCanFrames = findViewById(R.id.rv_can_frames);
        tvFrameCount = findViewById(R.id.tv_frame_count);
        tvProtocolStatus = findViewById(R.id.tv_protocol_status);

        // 设置RecyclerView
        frameList = new ArrayList<>();
        frameAdapter = new CanFrameAdapter(frameList);
        rvCanFrames.setLayoutManager(new LinearLayoutManager(this));
        rvCanFrames.setAdapter(frameAdapter);

        updateConnectionStatus(false);
        updateProtocolStatus("支持协议: CAN 2.0 / J1939");
    }

    /**
     * 初始化数据
     */
    private void initData() {
        canManager = CanManager.getInstance(this);
        canManager.addDataListener(this);
        canManager.addStatusListener(this);
    }

    /**
     * 设置监听器
     */
    private void setupListeners() {
        btnConnect.setOnClickListener(v -> connectToCan());
        btnDisconnect.setOnClickListener(v -> disconnectFromCan());
        btnSendTestData.setOnClickListener(v -> sendTestData());
        btnClearData.setOnClickListener(v -> clearData());
        btnSendCustom.setOnClickListener(v -> sendCustomData());
        btnSendJ1939Test.setOnClickListener(v -> sendJ1939TestData());
    }

    /**
     * 连接CAN总线
     */
    private void connectToCan() {
        Timber.d("开始连接CAN总线");
        if (canService != null) {
            canService.connectCan();
        } else {
            canManager.connect();
        }
        btnConnect.setEnabled(false);
        tvConnectionStatus.setText("连接中...");
    }

    /**
     * 断开CAN总线连接
     */
    private void disconnectFromCan() {
        Timber.d("断开CAN总线连接");
        if (canService != null) {
            canService.disconnectCan();
        } else {
            canManager.disconnect();
        }
    }

    /**
     * 发送测试数据
     */
    private void sendTestData() {
        boolean isConnected = (canService != null) ? canService.isCanConnected() : canManager.isConnected();
        if (!isConnected) {
            Toast.makeText(this, "请先连接CAN总线", Toast.LENGTH_SHORT).show();
            return;
        }

        List<CanFrame> testFrames = CanTestDataGenerator.getAllTestFrames();
        for (CanFrame frame : testFrames) {
            // 记录发送的帧
            recordSentFrame(frame);

            if (canService != null) {
                canService.sendCanFrame(frame);
            } else {
                canManager.sendFrame(frame);
            }
            // 添加小延迟避免发送过快
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                break;
            }
        }

        Toast.makeText(this, "已发送 " + testFrames.size() + " 条CAN测试数据", Toast.LENGTH_SHORT).show();
    }

    /**
     * 发送J1939测试数据
     */
    private void sendJ1939TestData() {
        boolean isConnected = (canService != null) ? canService.isCanConnected() : canManager.isConnected();
        if (!isConnected) {
            Toast.makeText(this, "请先连接CAN总线", Toast.LENGTH_SHORT).show();
            return;
        }

        // 创建J1939测试帧
        List<J1939Frame> j1939TestFrames = createJ1939TestFrames();
        for (J1939Frame frame : j1939TestFrames) {
            // 将J1939帧转换为CAN帧发送
            CanFrame canFrame = frame.toCanFrame();

            // 记录发送的帧
            recordSentFrame(canFrame);

            if (canService != null) {
                canService.sendCanFrame(canFrame);
            } else {
                canManager.sendJ1939Frame(frame);
            }
            // 添加小延迟避免发送过快
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                break;
            }
        }

        Toast.makeText(this, "已发送 " + j1939TestFrames.size() + " 条J1939测试数据", Toast.LENGTH_SHORT).show();
    }

    /**
     * 创建J1939测试帧
     */
    private List<J1939Frame> createJ1939TestFrames() {
        List<J1939Frame> frames = new ArrayList<>();

        // EEC1 - 发动机转速测试数据
        J1939Frame eec1 = new J1939Frame();
        eec1.setPriority(3);
        eec1.setPgn(J1939Constants.PGN_EEC1);
        eec1.setSourceAddress(0x00);
        eec1.setData(new byte[]{(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x60, (byte) 0x09, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF});
        eec1.setPgnName("电子发动机控制器1");
        eec1.setSpnName("发动机转速: 2400 RPM");
        frames.add(eec1);

        // CCVS - 车辆速度测试数据
        J1939Frame ccvs = new J1939Frame();
        ccvs.setPriority(6);
        ccvs.setPgn(J1939Constants.PGN_CRUISE_CONTROL_VEHICLE_SPEED);
        ccvs.setSourceAddress(0x17);
        ccvs.setData(new byte[]{(byte) 0xFF, (byte) 0x50, (byte) 0x14, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF});
        ccvs.setPgnName("巡航控制/车辆速度");
        ccvs.setSpnName("车辆速度: 80.3 km/h");
        frames.add(ccvs);

        // ET1 - 发动机温度测试数据
        J1939Frame et1 = new J1939Frame();
        et1.setPriority(6);
        et1.setPgn(J1939Constants.PGN_ENGINE_TEMPERATURE_1);
        et1.setSourceAddress(0x00);
        et1.setData(new byte[]{(byte) 0x5A, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF});
        et1.setPgnName("发动机温度1");
        et1.setSpnName("冷却液温度: 50°C");
        frames.add(et1);

        return frames;
    }

    /**
     * 发送自定义数据
     */
    private void sendCustomData() {
        boolean isConnected = (canService != null) ? canService.isCanConnected() : canManager.isConnected();
        if (!isConnected) {
            Toast.makeText(this, "请先连接CAN总线", Toast.LENGTH_SHORT).show();
            return;
        }

        String canIdStr = etCanId.getText().toString().trim();
        String canDataStr = etCanData.getText().toString().trim();

        if (canIdStr.isEmpty() || canDataStr.isEmpty()) {
            Toast.makeText(this, "请输入CAN ID和数据", Toast.LENGTH_SHORT).show();
            return;
        }

        try {
            int canId = Integer.parseInt(canIdStr, 16);
            CanFrame frame = CanTestDataGenerator.createCustomFrame(canId, canDataStr);

            // 记录发送的帧
            recordSentFrame(frame);

            if (canService != null) {
                canService.sendCanFrame(frame);
            } else {
                canManager.sendFrame(frame);
            }

            Toast.makeText(this, "自定义数据发送成功", Toast.LENGTH_SHORT).show();

            // 清空输入框
            etCanId.setText("");
            etCanData.setText("");

        } catch (NumberFormatException e) {
            Toast.makeText(this, "CAN ID格式错误，请输入十六进制数值", Toast.LENGTH_SHORT).show();
        } catch (Exception e) {
            Toast.makeText(this, "发送失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * 清空数据
     */
    private void clearData() {
        frameList.clear();
        frameAdapter.notifyDataSetChanged();
        canManager.clearReceivedFrames();
        updateFrameCount();
        Toast.makeText(this, "数据已清空", Toast.LENGTH_SHORT).show();
    }

    /**
     * 更新连接状态显示
     */
    private void updateConnectionStatus(boolean connected) {
        if (connected) {
            tvConnectionStatus.setText("已连接");
            tvConnectionStatus.setTextColor(getResources().getColor(android.R.color.holo_green_dark));
            btnConnect.setEnabled(false);
            btnDisconnect.setEnabled(true);
            btnSendTestData.setEnabled(true);
            btnSendCustom.setEnabled(true);
            btnSendJ1939Test.setEnabled(true);
        } else {
            tvConnectionStatus.setText("未连接");
            tvConnectionStatus.setTextColor(getResources().getColor(android.R.color.holo_red_dark));
            btnConnect.setEnabled(true);
            btnDisconnect.setEnabled(false);
            btnSendTestData.setEnabled(false);
            btnSendCustom.setEnabled(false);
            btnSendJ1939Test.setEnabled(false);
        }
    }

    /**
     * 更新帧计数显示
     */
    private void updateFrameCount() {
        tvFrameCount.setText("接收帧数: " + frameList.size());
    }

    /**
     * 更新协议状态显示
     */
    private void updateProtocolStatus(String status) {
        if (tvProtocolStatus != null) {
            tvProtocolStatus.setText(status);
        }
    }

    /**
     * 记录发送的帧
     */
    private void recordSentFrame(CanFrame frame) {
        String frameId = generateFrameId(frame);
        sentFrameIds.add(frameId);

        // 清理过期的记录（避免内存泄漏）
        // 如果记录数量过多，清理最早的一些记录
        if (sentFrameIds.size() > 1000) {
            // 简单的清理策略：清空一半
            Set<String> newSet = new HashSet<>();
            int count = 0;
            for (String id : sentFrameIds) {
                if (count++ > 500) {
                    newSet.add(id);
                }
            }
            sentFrameIds = newSet;
        }
    }

    /**
     * 生成帧的唯一标识
     * 基于CAN ID和数据内容生成
     */
    private String generateFrameId(CanFrame frame) {
        StringBuilder sb = new StringBuilder();
        sb.append(frame.getCanId()).append("_");

        byte[] data = frame.getData();
        if (data != null && data.length > 0) {
            // 只使用前4字节或关键字节，避免动态数据影响
            int len = Math.min(4, data.length);
            for (int i = 0; i < len; i++) {
                sb.append(String.format("%02X", data[i]));
            }
        }

        // 添加发送时间戳（100ms精度）
        sb.append("_").append(System.currentTimeMillis() / 100);
        return sb.toString();
    }

    // CanDataListener 接口实现
    @Override
    public void onFrameReceived(CanFrame frame) {
        runOnUiThread(() -> {
            // 检查是否为自己发送的帧
            String frameId = generateFrameId(frame);
            boolean isSelfSent = sentFrameIds.contains(frameId);

            // 如果是自己发送的帧，从记录中移除（避免内存泄漏）
            if (isSelfSent) {
                sentFrameIds.remove(frameId);
            }

            frameList.add(0, frame); // 新数据插入到顶部

            // 限制显示的帧数量
            if (frameList.size() > 500) {
                frameList.remove(frameList.size() - 1);
            }

            frameAdapter.notifyItemInserted(0);
            rvCanFrames.scrollToPosition(0);
            updateFrameCount();

            // 解析并显示数据
            CanDataParser.ParseResult result = CanDataParser.parseFrame(frame);

            // 区分显示日志
            if (isSelfSent) {
                Timber.d("接收到自己发送的CAN帧: %s -> %s", frame.toString(), result.toString());
                updateProtocolStatus("最后接收: CAN 2.0 帧 (自发)");
            } else {
                Timber.d("接收到其他设备的CAN帧: %s -> %s", frame.toString(), result.toString());
                updateProtocolStatus("最后接收: CAN 2.0 帧 (他发)");
            }
        });
    }

    @Override
    public void onJ1939DataReceived(J1939Frame frame) {
        runOnUiThread(() -> {
            // 将J1939帧转换为CanFrame显示
            CanFrame canFrame = frame.toCanFrame();

            // 检查是否为自己发送的帧
            String frameId = generateFrameId(canFrame);
            boolean isSelfSent = sentFrameIds.contains(frameId);

            // 如果是自己发送的帧，从记录中移除（避免内存泄漏）
            if (isSelfSent) {
                sentFrameIds.remove(frameId);
            }

            frameList.add(0, canFrame);

            // 限制显示的帧数量
            if (frameList.size() > 500) {
                frameList.remove(frameList.size() - 1);
            }

            frameAdapter.notifyItemInserted(0);
            rvCanFrames.scrollToPosition(0);
            updateFrameCount();

            // 解析并显示J1939数据
            J1939DataParser.J1939ParseResult result = J1939DataParser.parseFrame(frame);

            // 区分显示日志
            if (isSelfSent) {
                Timber.d("接收到自己发送的J1939帧: %s -> %s", frame.toString(), result.toString());
                updateProtocolStatus(String.format("最后接收: J1939 PGN=0x%X (%s) (自发)",
                        frame.getPgn(), result.getPgnName()));
            } else {
                Timber.d("接收到其他设备的J1939帧: %s -> %s", frame.toString(), result.toString());
                updateProtocolStatus(String.format("最后接收: J1939 PGN=0x%X (%s) (他发)",
                        frame.getPgn(), result.getPgnName()));
            }
        });
    }

    @Override
    public void onFrameSent(CanFrame frame) {
        runOnUiThread(() -> {
            // 发送的帧也显示在列表中，但用不同颜色标识
            frame.setTimestamp(System.currentTimeMillis());
            frameList.add(0, frame);

            if (frameList.size() > 500) {
                frameList.remove(frameList.size() - 1);
            }

            frameAdapter.notifyItemInserted(0);
            rvCanFrames.scrollToPosition(0);
            updateFrameCount();

            Timber.d("发送CAN帧: %s", frame.toString());
        });
    }

    // CanStatusListener 接口实现
    @Override
    public void onConnected() {
        runOnUiThread(() -> {
            updateConnectionStatus(true);
            Toast.makeText(this, "CAN总线连接成功", Toast.LENGTH_SHORT).show();
        });
    }

    @Override
    public void onDisconnected() {
        runOnUiThread(() -> {
            updateConnectionStatus(false);
            Toast.makeText(this, "CAN总线已断开", Toast.LENGTH_SHORT).show();
        });
    }

    @Override
    public void onError(String error) {
        runOnUiThread(() -> {
            Toast.makeText(this, "CAN通信错误: " + error, Toast.LENGTH_LONG).show();
            updateConnectionStatus(false);
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        // 解绑服务
        if (isServiceBound && canService != null) {
            canService.removeServiceListener(this);
            unbindService(serviceConnection);
            isServiceBound = false;
        }

        if (canManager != null) {
            canManager.removeDataListener(this);
            canManager.removeStatusListener(this);
            canManager.release();
        }
    }

    /**
     * 启动并绑定服务
     */
    private void startAndBindService() {
        serviceIntent = new Intent(this, CanCommunicationService.class);

        // 启动服务
        startService(serviceIntent);

        // 绑定服务
        bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
    }

    /**
     * 服务连接
     */
    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            CanCommunicationService.CanServiceBinder binder =
                    (CanCommunicationService.CanServiceBinder) service;
            canService = binder.getService();
            isServiceBound = true;

            // 添加服务监听器
            canService.addServiceListener(MainActivity.this);

            Timber.d("CAN通信服务已连接");

            // 更新UI状态
            runOnUiThread(() -> {
                updateConnectionStatus(canService.isCanConnected());
                updateFrameCount();
            });
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            canService = null;
            isServiceBound = false;
            Timber.d("CAN通信服务已断开");
        }
    };

    // CanCommunicationService.ServiceListener 接口实现
    @Override
    public void onServiceStatusChanged(boolean isRunning) {
        runOnUiThread(() -> {
            Timber.d("服务状态变化: %s", isRunning ? "运行中" : "已停止");
            // 可以在这里更新UI显示服务状态
        });
    }

    @Override
    public void onDataStatisticsUpdated(int receivedCount, int sentCount) {
        runOnUiThread(() -> {
            // 更新数据统计显示
            String statsText = String.format("服务统计 - 接收: %d, 发送: %d", receivedCount, sentCount);
            updateProtocolStatus(statsText);
        });
    }
}